Skip to content

[FEATURE] add pytta.bs1770 with loudness, loudness range and true peak - #71

Open
aguirreSL wants to merge 1 commit into
PyTTaMaster:developmentfrom
aguirreSL:dev-bs1770
Open

aguirreSL wants to merge 1 commit into
PyTTaMaster:developmentfrom
aguirreSL:dev-bs1770

Conversation

@aguirreSL

@aguirreSL aguirreSL commented Oct 31, 2026 •

Copy link
Copy Markdown

Adds the module pytta.bs1770 with the loudness measures used in broadcast and streaming:

  1. loudness(signalObj, weights=None): integrated loudness in LUFS of ITU-R BS.1770-5, with K-weighting, 400 ms blocks overlapping by 75 %, the absolute gate at -70 LUFS, the relative gate 10 LU below, and channel weights (Table 3; 1.41 for surround channels, 0 for LFE).
  2. momentary(signalObj) and short_term(signalObj): the 400 ms and 3 s loudness of EBU Tech 3341, every 100 ms, with the time of the end of each window.
  3. loudness_range(signalObj): LRA of EBU Tech 3342, following its MATLAB reference code, including the percentile indexing.
  4. true_peak(signalObj): true-peak level in dBTP with the 4-phase, order-48 interpolating filter of BS.1770-5 Annex 2.

The Recommendation gives the K-weighting coefficients at 48 kHz and asks for the same response at other rates. k_weighting(fs) builds both biquads from analog prototypes (the parameters libebur128 also uses), which give Tables 1 and 2 at 48 kHz to 1e-10.

The tests in tests/test_bs1770.py synthesize the minimum requirement test signals of the EBU documents and check their expected responses:

Tech 3341 / 3342 case Expected Measured
3341 cases 1, 2 (steady tones, M, S and I) -23.0, -33.0 ±0.1 LUFS -22.99, -32.99
3341 case 6 (5.0 channels, surround weights) -23.0 ±0.1 LUFS within tolerance
3341 cases 3, 4, 5 (gating) -23.0 ±0.1 LUFS -23.01, -23.01, -22.98
3341 cases 9, 12 (3 s and 400 ms windows) -23.0 ±0.1 LUFS, constant within tolerance
3342 cases 1 to 4 (LRA) 10, 5, 20, 15 ±1 LU 10.00, 5.00, 20.00, 15.00
3341 cases 15 to 19 (true peak) -6.0 / +3.0, +0.2 / -0.4 dBTP -6.02, -5.98, -6.31, -6.03, +3.03

The authentic programme cases and true-peak cases 20 to 23 are not included, since they need the EBU audio files or a 4 fs synthesis.

Checked with Python 3.12, numpy 1.26 and scipy 1.17. The existing tests behave as on development: the 7 failures there (3 in test_h5io.py, 4 in test_pyttasave.py) are the same with and without this change.

Sources: ITU-R BS.1770-5, EBU Tech 3341, EBU Tech 3342.

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com

Integrated loudness of ITU-R BS.1770-5 (K-weighting, 400 ms blocks with
75 % overlap, absolute and relative gates, channel weights of Table 3),
momentary and short-term loudness of EBU Tech 3341, loudness range of
EBU Tech 3342 and the true-peak level of BS.1770-5 Annex 2 with its
4-phase interpolating filter. The K-weighting is built from analog
prototypes that give Tables 1 and 2 at 48 kHz and the same response at
other rates.

Tests synthesize the minimum requirement test signals of Tech 3341
(cases 1 to 6, 9, 12, 15 to 19) and Tech 3342 (cases 1 to 4) and check
their expected responses and tolerances.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant